package com.jiantong.work.impl.service;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.user.ext.LoginUser;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.enums.ProductionReportStatus;
import com.jiantong.work.impl.dao.ProductionReportDao;
import com.jiantong.work.model.ProductionReport;
import com.jiantong.work.service.ProductionReportReadService;
import io.terminus.boot.rpc.common.annotation.RpcProvider;
import io.terminus.common.model.PageInfo;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by niufei on 2017/3/14.
 *
 */
@Slf4j
@Service
@RpcProvider
public class ProductionReportReadServiceImpl implements ProductionReportReadService{

    private final ProductionReportDao productionReportDao;

    @Autowired
    public ProductionReportReadServiceImpl(ProductionReportDao productionReportDao) {
        this.productionReportDao = productionReportDao;
    }

    /**
     * 根据id查询生产记录单条
     * @param id 主键 id
     * @return ProductionReport 对象
     */
    @Override
    public Response<ProductionReport> findById(Long id) {
        try{
            ProductionReport productionReport = productionReportDao.findById(id);
            if (productionReport == null) {
                log.error("productionReport(id={}) is not found", id);
                return Response.fail("productionReport.not.found");
            }
            return Response.ok(productionReport);
        }catch (Exception e){
            log.error("failed to find productionReport(id={}), cause:{}", id, Throwables.getStackTraceAsString(e));
            return Response.fail("productionReport.find.fail");
        }
    }

    @Override
    public Response<Map<String, Object>> findStatusById(Long id) {
        try{
            Integer status = productionReportDao.findStatusById(id);
            Map<String , Object> map = Maps.newHashMap();
            if(status == null){
                log.error("ProductionReport status (id={}) is not found", id);
                return Response.fail("ProductionReport.status.not.found");
            }
            map.put("status",status);
            return Response.ok(map);
        }catch (Exception e){
            log.error("ProductionReport status (id={}) is not found", id);
            return Response.fail("ProductionReport.status.not.found");
        }
    }

    /**
     * 养殖端按状态查询当前养殖场的生产记录列表
     */
    @Override
    public Response<Paging<ProductionReport>> pagingProductionReport(Integer pageNo, Integer pageSize, Integer status,Long breedFactoryId) {
        try {
            PageInfo pageInfo = new PageInfo(pageNo, pageSize);
            Map<String, Object> criteria = Maps.newHashMap();

            if (status != null) criteria.put("status", status);

            criteria.put("breedFactoryId",breedFactoryId);

            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            return Response.ok(productionReportDao.paging(pageInfo.getOffset(), pageInfo.getLimit(), criteria));
        } catch (Exception e) {
            log.error("failed to find pollutionControl{}, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("pollutionControl.find.fail");
        }
    }

    /**
     *按从日期、到日期和养殖场名称查询本市养殖场生产记录列表
     */
    @Override
    public Response<Paging<ProductionReport>> pagingProductionReports(Integer pageNo, Integer pageSize, Long breedFactoryId,Integer breedType, Date fromDate, Date toDate) {
        try {
            PageInfo pageInfo = new PageInfo(pageNo, pageSize);
            Map<String, Object> criteria = Maps.newHashMap();

            List<Long> breedFactoryIds = new ArrayList<>();
            if(breedFactoryId!=null) {
                breedFactoryIds.add(breedFactoryId);
            }else {
                LoginUser loginUser = UserUtil.getCurrentUser();
                breedFactoryIds = loginUser.getBreedFactoryIds();
            }
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds",breedFactoryIds);
            else return Response.ok(new Paging<ProductionReport>(0L,new ArrayList<>()));

            if(fromDate!=null) criteria.put("fromDate", fromDate);

            if(toDate != null) criteria.put("toDate",toDate);

            if(breedType != null) criteria.put("breedType",breedType);

            criteria.put("status", ProductionReportStatus.FINISHED.value());
            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            return Response.ok(productionReportDao.pagingProductionReports(pageInfo.getOffset(), pageInfo.getLimit(), criteria));
        } catch (Exception e) {
            log.error("failed to find ProductionReport breedFactoryId={},fromDate={},toDate={}),cause:{}",breedFactoryId, fromDate,toDate,Throwables.getStackTraceAsString(e));
            return Response.fail("ProductionReport.find.fail");
        }
    }

    /**
     * 政府端按物种统计存栏数合计值
     */
    @Override
    public Response<List<Map<String , Object>>> sumSpeciesStatistics(Long breedFactoryId) {
        try{
            Map<String , Object> criteria = Maps.newHashMap();
            List<Long> breedFactoryIds = new ArrayList<>();
            if(breedFactoryId!=null) {
                breedFactoryIds.add(breedFactoryId);
            }else {
                LoginUser loginUser = UserUtil.getCurrentUser();
                breedFactoryIds = loginUser.getBreedFactoryIds();
            }
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds",breedFactoryIds);
            else return Response.ok(new ArrayList<>());
            criteria.put("status",ProductionReportStatus.FINISHED.value());
            criteria.put("deleteFlag",DocumentsDeleteFlag.NORMAL.value());
            return Response.ok(productionReportDao.sumSpeciesStatistics(criteria));
        }catch (Exception e){
            log.error("failed to find sumSpeciesStatistics{}, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("sumSpeciesStatistics.find.fail");
        }
    }

    /**
     *
     * @param breedFactoryIds 养殖场ids
     * @return List<Map<String, Object>>
     */
    @Override
    public Response<List<Map<String, Object>>> sumChangeQuantityByAnimalType(List<Long> breedFactoryIds) {
        try{
            Map<String , Object> criteria = Maps.newHashMap();
            if(breedFactoryIds != null){
                criteria.put("breedFactoryIds",breedFactoryIds);
            }
            criteria.put("status",ProductionReportStatus.FINISHED.value());
            criteria.put("deleteFlag",DocumentsDeleteFlag.NORMAL.value());
            return Response.ok(productionReportDao.sumChangeQuantityByAnimalType(criteria));
        }catch (Exception e){
            log.error("failed to find sum change quantity, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("change.quantity.find.fail");
        }
    }

    /**
     *
     * @param pageNo 页码
     * @param pageSize 每页多少条
     * @param fromDate 从日期
     * @param toDate 到日期
     * @param breedFactoryIds 养殖场ids
     * @return Response<Paging<ProductionReport>>
     */
    @Override
    public Response<Paging<ProductionReport>> pagingProductionReportByArea(Integer pageNo, Integer pageSize, Date fromDate, Date toDate, List<Long> breedFactoryIds) {
        try {
            PageInfo pageInfo = new PageInfo(pageNo, pageSize);
            Map<String, Object> criteria = Maps.newHashMap();
            if(breedFactoryIds != null){
                criteria.put("breedFactoryId",breedFactoryIds);
            }
            if(fromDate != null){
                criteria.put("fromDate",fromDate);
            }

            if(toDate != null){
                criteria.put("toDate",toDate);
            }
            criteria.put("status", ProductionReportStatus.FINISHED.value());
            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            return Response.ok(productionReportDao.pagingProductionReportByArea(pageInfo.getOffset(), pageInfo.getLimit(), criteria));
        } catch (Exception e) {
            log.error("failed to find ProductionReport breedFactoryIds={},fromDate={},toDate={}),cause:{}",breedFactoryIds, fromDate,toDate,Throwables.getStackTraceAsString(e));
            return Response.fail("ProductionReport.find.fail");
        }
    }

    /**
     * 养殖端存栏数合计值（只统计当前养殖场已生效，状态写死）
     */
    @Override
    public Response<Map> sumRestockBreedFactoryId(Long breedFactoryId) {
        try{
            Map<String , Object> criteria = Maps.newHashMap();

            criteria.put("breedFactoryId",breedFactoryId);

            criteria.put("status",ProductionReportStatus.FINISHED.value());

            criteria.put("deleteFlag",DocumentsDeleteFlag.NORMAL.value());

            return Response.ok(productionReportDao.aquacultureSum(criteria));
        }catch (Exception e){
            log.error("failed to find aquacultureSum{}, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("aquacultureSum.find.fail");
        }
    }

    /**
     *根据时间起始 状态 提交未提交  养殖厂查询
     */

    public Response<Paging<ProductionReport>> pagingbytimes (Integer pageNo, Integer pageSize, Map<String,Object> criteria){

        try{ PageInfo pageInfo = new PageInfo(pageNo, pageSize);

            return Response.ok(productionReportDao.pagingbytimes(pageInfo.getOffset(), pageInfo.getLimit(),criteria));


        }catch(Exception e){
            log.error("failed to find pagingbytimes{}, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("pagingbytimes.find.fail");
        }

    }

    /**
     * 根据第三种类 分组求和
     *
     * @return List<Map<String , Object>>
     */
    @Override
    public Response<List<Map<String, Object>>> countSumByThirdType(Long breedFactoryId) {
        try{
            Map<String , Object> criteria = Maps.newHashMap();

            criteria.put("breedFactoryId",breedFactoryId);

            criteria.put("status",ProductionReportStatus.FINISHED.value());

            criteria.put("deleteFlag",DocumentsDeleteFlag.NORMAL.value());

            return Response.ok(productionReportDao.countSumByThirdType(criteria));
        }catch (Exception e){
            log.error("failed to find aquacultureSum{}, cause:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("aquacultureSum.find.fail");
        }
    }

    @Override
    public ProductionReport findProductByRelateId(Long relateId) {
        return productionReportDao.findProductByRelateId(relateId);
    }

    @Override
    public Response<Map<String, Object>> findSumForWeb(Map<String, Object> map) {
        try{
            return Response.ok(productionReportDao.findSumForWeb(map));
        }catch (Exception e){
            log.error("failed to sum , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to sum");
        }
    }
}
